home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / textmap.zip / TEXTURE.TXT < prev   
Internet Message Format  |  1993-12-15  |  6KB

  1. From: robert@stud.unit.no (Robert Schmidt)
  2. Newsgroups: rec.games.programmer
  3. Subject: Re: Texture mapping sources wanted
  4.  
  5. This is not a source file, but rather a short document containing what
  6. little I know about texture mapping arbitrarily positioned and rotated
  7. prallellograms in 3D space.  It also contains a GIF file which probably
  8. is needed to understand what is going on.  I know one person who has
  9. used the formulas presented to implement correct texture mapping
  10. of 3D triangles.
  11.  
  12. Concerning Digital Image Warping:  on the subjects of texture mapping,
  13. it contains little more than what you can read below.  It does provide
  14. some faster approximations though, but they don't look to good in the 
  15. general case.
  16.  
  17. ---------------------------------------------- use a chainsaw here
  18.  
  19.                    My idea of texture mapping
  20.            Mapping a 2D bitmap to a 3D parallellogram
  21.  
  22.    by Robert Schmidt (robert@alkymi.unit.no) of Ztiff Zox Softwear
  23.  
  24.  
  25. This is an introductory text which might not be particularly useful, but it
  26. might get you started, and might be the start of some good (I mean FAST!)
  27. public domain source code for texture mapping.  No source code is
  28. included, but a 640x480 B&W GIF-sketch is appended uuencoded at the
  29. end of this text.
  30.  
  31. See the accompanying IDEA.GIF when you get bewildered.  I'll use lower
  32. case letters for scalars, and capital letters for vectors in this text.
  33. I drew the image before trying to incorporate underlining in this ASCII
  34. text... :-)  Thus:
  35.  
  36. In this text:
  37.   a is a scalar,
  38.   A is a vector (NOT a matrix).
  39. In the drawing:
  40.   a is a scalar,
  41.   a-underlined is the vector.
  42.  
  43.  
  44. Assume the following:
  45.  
  46. o The origo (0,0,0) of our world is positioned right in your eye.
  47.   (Ouch!)  Choose left or right yourself.  The x axis points right of
  48.   your head, the y axis points up, and the z axis points straight ahead
  49.   of you.
  50.  
  51. o A four sided parallellogram, is spanned out in 3D space by two vectors 
  52.   U and V.  The common base of the two vectors is given by the base vector
  53.   B.
  54.  
  55. o Your computer screen is positioned a fixed distance from your
  56.   eye/origo.  The origo of the screen is at (0,0,zs).  The xy-plane of
  57.   your screen is parallell to the world xy-plane.
  58.  
  59. o Stored somewhere else is a bitmap, which is to be mapped onto the
  60.   parallellogram, so that the base of the bitmap coincides with the base
  61.   (B) of the parallellogram, and the edges of the two fall together.
  62.  
  63. Now our goal is made up of two smaller goals:
  64.  
  65. 1) Map the bitmap to the parallellogram.
  66. 2) Map the parallellogram to the screen.
  67.  
  68. I assume you are familiar with drawing a 3D polygon on screen, i.e.
  69. performing a perspective transform of the coordinates and rasterizing 
  70. the edges.  This process, i.e. goal 2, isn't really the issue here.
  71.  
  72. The idea is that for each point S=<xs,ys,zs> on the screen that is
  73. contained in the polygon, we have to find the coordinates (u,v) along
  74. the vectors (U,V).  The corresponding point in space is given by
  75.  
  76. P = B + uU + vV
  77.  
  78. u and v will be in the interval [0,1] if P is within the polygon.  This
  79. is crucial.
  80.  
  81. Now if the 3D point P is to map to the screen pixel S, the vectors P and
  82. S have to be parallell.  Moreover, since they both are based in origo,
  83. they lie on the same line in space, thus:
  84.  
  85. P = tS
  86.  
  87. for some constant t.  Thus:
  88.  
  89. tS = B + uU + vV
  90.  
  91. Now we have 3 equations in 3 unknowns, t, u and v:
  92.  
  93. t sx = bx + u ux + v vx
  94. t sy = by + u uy + v vy
  95. t sz = bz + u uz + v vz
  96.  
  97. t is of no interest to us, so I'll just show the solutions for u and v:
  98.  
  99.     d sx + e sy + f sz
  100. u = ------------------
  101.     a sx + b sy + c sz
  102.                                 (1)
  103.     g sx + h sy + i sz
  104. v = ------------------
  105.     a sx + b sy + c sz
  106.  
  107. where a,b,c,d,e,f,g,h,i are all constants which are calculated once each
  108. time the bitmap is moved/redrawn:
  109.  
  110. a = uy vz - vy uz
  111. b = vx uz - ux vz
  112. c = ux vy - vx uy
  113.  
  114. d = vy bz - by vz
  115. e = bx vz - vx bz
  116. f = vx by - bx vy
  117.  
  118. g = by uz - uy bz
  119. h = ux bz - bx uz
  120. i = bx uy - ux by
  121.  
  122. The straightforward algorithm to draw the bitmap is as follows:
  123.  
  124. for (ys=0; ys<200; ys++)
  125.   for (xs=0; xs<320; xs++)
  126.     calculate u,v from (1)
  127.     if (u in [0,1) and v in [0,1)
  128.       putpixel (xs, ys, bitmap[u*xsize, v*ysize])
  129.  
  130. This will scan through each pixel on the screen, check wether the pixel
  131. is mapped inside the bitmap, and plot the bitmap pixel to the screen
  132. if it is.
  133.  
  134. Calculating (1) for each pixel is time consuming, but there are facts to
  135. exploit for significant speed gains:
  136.  
  137. 1) sz (the eye z-coordinate of the screen pixel) is constant, so all 
  138.    products involving sz can be calculated outside all loops.
  139.  
  140. 2) sy is constant on each raster line, so the products involving sy need
  141.    be calculated only once per line, i.e. outside the xs loop.
  142.  
  143. 3) Scan convert the polygon (parallellogram) to screen coordinates, and
  144.    calculate (u,v) only for pixels inside the polygon.  I'm not going to
  145.    say more about this, but it's the obvious way to go!
  146.  
  147. 4) The denominators in (1) are equal for u and v, so it need only be
  148.    evaluated once for each pixel.
  149.  
  150. 5) Try to incrementalize.  Instead of calculating (d sx) when x
  151.    increases, just add d to the previous value, for example.
  152.  
  153.  
  154. The problem is I still can't get away with less than 1 divsion and 2
  155. multiplications per pixel, alternatively 2 divisions.  There are ways to
  156. approximate this, for example by subdividing the polygon and using first
  157. or second degree Taylor polynomials, combined with the use of forward
  158. differences.  Third degree polynomials don't give much quality gain over
  159. second degree polynomials, and take more initial calculations.  These are
  160. all approximations, and will give visible artifacts and errors.  
  161. Subdividing helps on this, but is expensive.
  162.  
  163. I'm looking for an incremental algorithm similar to the Bresenham
  164. algorithms for drawing straight lines or ellipses.  This would give an 
  165. exact perspective mapping and *not* an approximation.  At the moment, I'm
  166. literaly halfway there, it's just that the second half seems impossible
  167. to figure out.  I am able to get it right as long as each and every pixel
  168. in the texture bitmap is used at least once.  If one or more bitmap
  169. pixels are to be skipped, my algorithm fails.  Interested persons
  170. mail me.
  171.  
  172. Mail any comments and ideas to robert@alkymi.unit.no.
  173.